Padroneggia il rimodellamento dei dati con le tabelle pivot di Python Pandas. Un'analisi approfondita di sintassi, tecniche avanzate ed esempi pratici per l'analisi dei dati globali.
Tabelle Pivot di Python Pandas: Una Guida Completa al Rimodellamento dei Dati
Nel mondo dell'analisi dei dati, la capacità di riassumere, aggregare e ristrutturare i dati non è solo un'abilità, è un superpotere. I dati grezzi, nella loro forma nativa, spesso assomigliano a un registro tentacolare e dettagliato. Sono ricchi di informazioni ma difficili da interpretare. Per estrarre spunti significativi, dobbiamo trasformare questo registro in un riassunto conciso. È proprio qui che eccellono le tabelle pivot e, per i programmatori Python, la libreria Pandas fornisce uno strumento potente e flessibile: pivot_table().
Questa guida è pensata per un pubblico globale di analisti di dati, scienziati e appassionati di Python. Approfondiremo i meccanismi delle tabelle pivot di Pandas, passando dai concetti fondamentali alle tecniche avanzate. Che si tratti di riassumere i dati di vendita di diversi continenti, analizzare dati climatici tra regioni o monitorare le metriche di progetto per un team distribuito, padroneggiare le tabelle pivot cambierà radicalmente il vostro approccio all'esplorazione dei dati.
Cos'è Esattamente una Tabella Pivot?
Se avete mai usato software per fogli di calcolo come Microsoft Excel o Google Sheets, probabilmente avete familiarità con il concetto di tabella pivot. È una tabella interattiva che consente di riorganizzare e riassumere colonne e righe di dati selezionate da un set di dati più ampio per ottenere il report desiderato.
Una tabella pivot svolge due funzioni chiave:
- Aggregazione: Calcola una statistica di riepilogo (come una somma, una media o un conteggio) per dati numerici raggruppati per una o più categorie.
- Rimodellamento: Trasforma i dati da un formato 'long' a un formato 'wide'. Invece di avere tutti i valori in una singola colonna, 'ruota' (pivot) i valori univoci di una colonna in nuove colonne nell'output.
La funzione pivot_table() di Pandas porta questa potente funzionalità direttamente nel vostro flusso di lavoro di analisi dati in Python, consentendo un rimodellamento dei dati riproducibile, programmabile e scalabile.
Configurazione dell'Ambiente e Dati di Esempio
Prima di iniziare, assicuratevi di avere installato la libreria Pandas. In caso contrario, potete installarla usando pip, il gestore di pacchetti di Python:
pip install pandas
Ora, importiamola nel nostro script Python o notebook:
import pandas as pd
import numpy as np
Creazione di un Dataset di Vendite Globali
Per rendere i nostri esempi pratici e rilevanti a livello globale, creeremo un dataset sintetico che rappresenta i dati di vendita di un'azienda di e-commerce multinazionale. Questo dataset includerà informazioni sulle vendite da diverse regioni, paesi e categorie di prodotti.
# Create a dictionary of data
data = {
'TransactionID': range(1, 21),
'Date': pd.to_datetime([
'2023-01-15', '2023-01-16', '2023-01-17', '2023-02-10', '2023-02-11',
'2023-02-12', '2023-03-05', '2023-03-06', '2023-03-07', '2023-01-20',
'2023-01-21', '2023-02-15', '2023-02-16', '2023-03-10', '2023-03-11',
'2023-01-18', '2023-02-20', '2023-03-22', '2023-01-25', '2023-02-28'
]),
'Region': [
'North America', 'Europe', 'Asia', 'North America', 'Europe', 'Asia', 'North America', 'Europe', 'Asia', 'Europe',
'Asia', 'North America', 'Europe', 'Asia', 'North America', 'Asia', 'Europe', 'North America', 'Europe', 'Asia'
],
'Country': [
'USA', 'Germany', 'Japan', 'Canada', 'France', 'India', 'USA', 'UK', 'China', 'Germany',
'Japan', 'USA', 'France', 'India', 'Canada', 'China', 'UK', 'USA', 'Germany', 'India'
],
'Product_Category': [
'Electronics', 'Apparel', 'Electronics', 'Books', 'Apparel', 'Electronics', 'Books', 'Electronics', 'Apparel',
'Apparel', 'Books', 'Electronics', 'Books', 'Apparel', 'Electronics', 'Books', 'Apparel', 'Books', 'Electronics', 'Electronics'
],
'Units_Sold': [10, 5, 8, 20, 7, 12, 15, 9, 25, 6, 30, 11, 18, 22, 14, 28, 4, 16, 13, 10],
'Unit_Price': [1200, 50, 900, 15, 60, 1100, 18, 950, 45, 55, 12, 1300, 20, 40, 1250, 14, 65, 16, 1150, 1050]
}
# Create DataFrame
df = pd.DataFrame(data)
# Calculate Revenue
df['Revenue'] = df['Units_Sold'] * df['Unit_Price']
# Display the first few rows of the DataFrame
print(df.head())
Questo dataset ci fornisce una solida base con un mix di dati categorici (Region, Country, Product_Category), dati numerici (Units_Sold, Revenue) e dati di serie temporali (Date).
L'Anatomia di pivot_table()
La funzione pivot_table() di Pandas è incredibilmente versatile. Analizziamo i suoi parametri più importanti:
pandas.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, margins_name='All')
- data: Il DataFrame che si desidera trasformare.
- values: La/e colonna/e contenente/i i dati da aggregare. Se non specificato, verranno utilizzate tutte le colonne numeriche rimanenti.
- index: La/e colonna/e i cui valori univoci formeranno le righe della nuova tabella pivot. A volte viene chiamata 'chiave di raggruppamento'.
- columns: La/e colonna/e i cui valori univoci verranno 'ruotati' per formare le colonne della nuova tabella.
- aggfunc: La funzione di aggregazione da applicare a 'values'. Può essere una stringa come 'sum', 'mean', 'count', 'min', 'max', o una funzione come
np.sum. Si può anche passare una lista di funzioni o un dizionario per applicare funzioni diverse a colonne diverse. Il valore predefinito è 'mean'. - fill_value: Un valore per sostituire eventuali risultati mancanti (NaN) nella tabella pivot.
- margins: Un booleano. Se impostato su
True, aggiunge subtotali per righe e colonne (noti anche come totale generale). - margins_name: Il nome per la riga/colonna che contiene i totali quando
margins=True. Il valore predefinito è 'All'.
La Vostra Prima Tabella Pivot: Un Esempio Semplice
Iniziamo con una comune domanda di business: "Qual è il fatturato totale generato da ciascuna categoria di prodotto?"
Per rispondere, dobbiamo:
- Usare
Product_Categoryper le righe (index). - Aggregare la colonna
Revenue(values). - Usare la somma come nostra funzione di aggregazione (aggfunc).
# Simple pivot table to see total revenue by product category
category_revenue = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
aggfunc='sum')
print(category_revenue)
Output:
Revenue
Product_Category
Apparel 1645
Books 1184
Electronics 56850
Istantaneamente, abbiamo un riepilogo chiaro e conciso. Il registro delle transazioni grezzo di 20 righe è stato rimodellato in una tabella di 3 righe che risponde direttamente alla nostra domanda. Questa è la potenza fondamentale di una tabella pivot.
Aggiungere una Dimensione per le Colonne
Ora, espandiamo il concetto. E se volessimo vedere il fatturato totale per categoria di prodotto, ma anche suddiviso per regione? È qui che entra in gioco il parametro columns.
# Pivot table with index and columns
revenue_by_category_region = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum')
print(revenue_by_category_region)
Output:
Region Asia Europe North America Product_Category Apparel 1125.0 625.0 NaN Books 336.0 360.0 488.0 Electronics 13200.0 14550.0 29100.0
Questo output è molto più ricco. Abbiamo 'ruotato' i valori univoci della colonna 'Region' ('Asia', 'Europe', 'North America') in nuove colonne. Ora possiamo facilmente confrontare le prestazioni delle diverse categorie di prodotto tra le regioni. Notiamo anche un valore NaN (Not a Number). Questo indica che nel nostro dataset non sono state registrate vendite di 'Apparel' per 'North America'. Questa è di per sé un'informazione preziosa!
Tecniche di Pivoting Avanzate
Le basi sono potenti, ma la vera flessibilità di pivot_table() si rivela nelle sue funzionalità avanzate.
Gestire i Valori Mancanti con fill_value
Il NaN nella nostra tabella precedente è accurato, ma per la reportistica o per calcoli futuri, potrebbe essere preferibile visualizzarlo come zero. Il parametro fill_value rende questa operazione semplice.
# Using fill_value to replace NaN with 0
revenue_by_category_region_filled = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum',
fill_value=0)
print(revenue_by_category_region_filled)
Output:
Region Asia Europe North America Product_Category Apparel 1125 625 0 Books 336 360 488 Electronics 13200 14550 29100
La tabella è ora più pulita e facile da leggere, specialmente per un pubblico non tecnico.
Lavorare con Indici Multipli (Indicizzazione Gerarchica)
E se aveste bisogno di raggruppare per più di una categoria sulle righe? Ad esempio, analizziamo le vendite per Region e poi per Country all'interno di ciascuna regione. Possiamo passare una lista di colonne al parametro index.
# Multi-level pivot table using a list for the index
multi_index_pivot = pd.pivot_table(df,
values='Revenue',
index=['Region', 'Country'],
aggfunc='sum',
fill_value=0)
print(multi_index_pivot)
Output:
Revenue
Region Country
Asia China 488
India 1760
Japan 10860
Europe France 1020
Germany 14440
UK 1115
North America Canada 17800
USA 12058
Pandas ha creato automaticamente un MultiIndex sulle righe. Questa struttura gerarchica è fantastica per approfondire i dati e vedere le relazioni nidificate. Potete applicare la stessa logica al parametro columns per creare colonne gerarchiche.
Usare Funzioni di Aggregazione Multiple
A volte, una singola statistica di riepilogo non è sufficiente. Potreste voler vedere sia il fatturato totale (somma) che la dimensione media della transazione (media) per ciascun gruppo. Potete passare una lista di funzioni a aggfunc.
# Using multiple aggregation functions
multi_agg_pivot = pd.pivot_table(df,
values='Revenue',
index='Region',
aggfunc=['sum', 'mean', 'count'])
print(multi_agg_pivot)
Output:
sum mean count
Revenue Revenue Revenue
Region
Asia 13108.000000 2184.666667 6
Europe 16575.000000 2762.500000 6
North America 29858.000000 4976.333333 6
Questo singolo comando ci fornisce un riepilogo completo: il fatturato totale, il fatturato medio per transazione e il numero di transazioni per ciascuna regione. Notate come Pandas crea colonne gerarchiche per mantenere l'output organizzato.
Applicare Funzioni Diverse a Valori Diversi
Potete essere ancora più granulari. Immaginate di voler vedere la somma di Revenue ma la media di Units_Sold. Potete passare un dizionario a aggfunc dove le chiavi sono i nomi delle colonne ('values') e i valori sono le funzioni di aggregazione desiderate.
# Different aggregations for different values
dict_agg_pivot = pd.pivot_table(df,
index='Region',
values=['Revenue', 'Units_Sold'],
aggfunc={
'Revenue': 'sum',
'Units_Sold': 'mean'
},
fill_value=0)
print(dict_agg_pivot)
Output:
Revenue Units_Sold
Region
Asia 13108 17.833333
Europe 16575 8.166667
North America 29858 14.333333
Questo livello di controllo è ciò che rende pivot_table() uno strumento di prim'ordine per l'analisi dati sofisticata.
Calcolare i Totali Generali con margins
A fini di reportistica, avere totali di riga e di colonna è spesso essenziale. L'argomento margins=True fornisce questa funzionalità senza alcuno sforzo aggiuntivo.
# Adding totals with margins=True
revenue_with_margins = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum',
fill_value=0,
margins=True,
margins_name='Grand Total') # Custom name for totals
print(revenue_with_margins)
Output:
Region Asia Europe North America Grand Total Product_Category Apparel 1125 625 0 1750 Books 336 360 488 1184 Electronics 13200 14550 29100 56850 Grand Total 14661 15535 29588 59784
Pandas calcola automaticamente la somma per ogni riga (il fatturato totale per categoria di prodotto in tutte le regioni) e per ogni colonna (il fatturato totale per regione in tutte le categorie), più un totale generale per tutti i dati nell'angolo in basso a destra.
Caso d'Uso Pratico: Analisi Basata sul Tempo
Le tabelle pivot non si limitano a categorie statiche. Sono incredibilmente utili per analizzare dati di serie temporali. Troviamo il fatturato totale per ogni mese.
Per prima cosa, dobbiamo estrarre il mese dalla nostra colonna 'Date'. Possiamo usare l'accessor .dt in Pandas per questo.
# Extract month from the Date column
df['Month'] = df['Date'].dt.month_name()
# Pivot to see monthly revenue by product category
monthly_revenue = pd.pivot_table(df,
values='Revenue',
index='Month',
columns='Product_Category',
aggfunc='sum',
fill_value=0)
# Optional: Order the months correctly
month_order = ['January', 'February', 'March']
monthly_revenue = monthly_revenue.reindex(month_order)
print(monthly_revenue)
Output:
Product_Category Apparel Books Electronics Month January 250 360 23100 February 795 794 24250 March 705 30 9500
Questa tabella ci offre una visione chiara delle performance di vendita di ciascuna categoria nel tempo, permettendoci di individuare facilmente tendenze, stagionalità o anomalie.
pivot_table() vs. groupby(): Qual è la Differenza?
Questa è una domanda comune per chi sta imparando Pandas. Le due funzioni sono strettamente correlate e, di fatto, pivot_table() è costruito sopra groupby().
groupby()è un'operazione più generale e fondamentale. Raggruppa i dati in base a determinati criteri e poi permette di applicare una funzione di aggregazione. Il risultato è tipicamente una Serie o un DataFrame di Pandas con un indice gerarchico, ma rimane in un formato 'long'.pivot_table()è uno strumento specializzato che esegue un raggruppamento e poi rimodella i dati. Il suo scopo principale è trasformare i dati da un formato lungo a un formato largo, che è spesso più leggibile per l'uomo.
Rivediamo il nostro primo esempio usando groupby():
# Same result as our first pivot table, but using groupby
category_revenue_groupby = df.groupby('Product_Category')['Revenue'].sum()
print(category_revenue_groupby)
Il risultato è una Serie di Pandas funzionalmente equivalente al DataFrame della nostra prima tabella pivot. Tuttavia, quando si introduce una seconda chiave di raggruppamento (come 'Region'), la differenza diventa chiara.
# Grouping by two columns
groupby_multi = df.groupby(['Product_Category', 'Region'])['Revenue'].sum()
print(groupby_multi)
Output (una Serie con un MultiIndex):
Product_Category Region
Apparel Asia 1125
Europe 625
Books Asia 336
Europe 360
North America 488
Electronics Asia 13200
Europe 14550
North America 29100
Name: Revenue, dtype: int64
Per ottenere lo stesso formato 'wide' di pivot_table(index='Product_Category', columns='Region'), dovreste usare groupby() seguito da unstack():
# Replicating a pivot table with groupby().unstack()
groupby_unstack = df.groupby(['Product_Category', 'Region'])['Revenue'].sum().unstack(fill_value=0)
print(groupby_unstack)
Questo produce esattamente lo stesso output della nostra tabella pivot con le colonne. Quindi, potete pensare a pivot_table() come a una comoda scorciatoia per il comune flusso di lavoro groupby().aggregate().unstack().
Quando usare quale?
- Usate
pivot_table()quando desiderate un output in formato largo e leggibile, specialmente per la reportistica o la creazione di tabelle di contingenza. - Usate
groupby()quando avete bisogno di maggiore flessibilità, state eseguendo calcoli intermedi in una pipeline di elaborazione dati, o quando il formato rimodellato e largo non è il vostro obiettivo finale.
Performance e Best Practice
Sebbene pivot_table() sia potente, è importante usarlo in modo efficiente, specialmente con dataset di grandi dimensioni.
- Prima Filtrare, Poi Trasformare: Se dovete analizzare solo un sottoinsieme dei vostri dati (ad es., le vendite dell'ultimo anno), filtrate il DataFrame prima di applicare la tabella pivot. Questo riduce la quantità di dati che la funzione deve elaborare.
- Usare Tipi Categorici: Per le colonne che usate frequentemente come indici o colonne nelle vostre tabelle pivot (come 'Region' o 'Product_Category'), convertitele al dtype 'category' in Pandas. Questo può ridurre significativamente l'uso della memoria e accelerare le operazioni di raggruppamento.
df['Region'] = df['Region'].astype('category') - Mantenere la Leggibilità: Evitate di creare tabelle pivot con troppi indici e colonne. Sebbene sia possibile, una tabella pivot larga centinaia di colonne e lunga migliaia di righe può diventare tanto illeggibile quanto i dati grezzi originali. Usatela per creare riepiloghi mirati.
- Comprendere l'Aggregazione: Siate consapevoli della vostra scelta di
aggfunc. Usare 'sum' sui prezzi non ha senso, mentre 'mean' potrebbe essere più appropriato. Assicuratevi sempre che la vostra aggregazione sia in linea con la domanda a cui state cercando di rispondere.
Conclusione: Il Vostro Strumento per Riepiloghi Approfonditi
La funzione pivot_table() di Pandas è uno strumento indispensabile nel toolkit di ogni analista di dati. Fornisce un modo dichiarativo, espressivo e potente per passare da dati disordinati e dettagliati a riepiloghi puliti e approfonditi. Comprendendo e padroneggiando i suoi componenti principali — values, index, columns, e aggfunc — e sfruttando le sue funzionalità avanzate come l'indicizzazione multi-livello, le aggregazioni personalizzate e i margini, potete rimodellare i vostri dati per rispondere a complesse domande di business con poche righe di codice Python.
La prossima volta che vi troverete di fronte a un grande dataset, resistete all'impulso di scorrere infinite righe. Invece, pensate alle domande a cui dovete rispondere e a come una tabella pivot possa rimodellare i vostri dati per rivelare le storie nascoste al loro interno. Buon pivoting!